package com.example.springlearning.consumer;

import com.example.springlearning.OrderService;
import com.example.springlearning.to.BatchOrderTo;
import com.example.springlearning.to.IBatchOrderTo;
import com.example.springlearning.to.SubtractStockSummary;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author luo
 * @description
 * @since 2022/8/9 10:01
 */
@Slf4j
public class BatchOrderConsumer implements Runnable {

    private final OrderService orderService;
    private final DelayQueue<BatchOrderTo> delayQueue;
    private final AtomicInteger stock;

    private volatile boolean shutdown;

    public BatchOrderConsumer(OrderService orderService, DelayQueue<BatchOrderTo> delayQueue, AtomicInteger stock) {

        this.orderService = orderService;
        this.delayQueue = delayQueue;
        this.stock = stock;
    }

    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {

                if (shutdown && delayQueue.isEmpty()) {
                    log.info("收到要关闭消费者的消息，并且现在延迟队列中的所有订单都已经处理完毕");
                    return;
                }
                IBatchOrderTo take = delayQueue.poll(1, TimeUnit.SECONDS);

                if(take==null){
                    continue;
                }

                int currentStock = stock.get();

                int currentAllSkuCount = take.getCurrentAllSkuCount();
                SubtractStockSummary subtractStockSummary = null;
                if (currentStock > currentAllSkuCount) {

                    if (stock.compareAndSet(currentStock, currentStock - currentAllSkuCount)) {
                        subtractStockSummary = orderService.batchSubtractStockSuccess(take.getSkuId());
                    } else {
                        subtractStockSummary = orderService.batchSubtractStockFail(take.getSkuId());
                    }
                } else {
                    subtractStockSummary = orderService.greedySubtractStock(take.getSkuId(), stock);

                    log.info("库存不够批量扣减，现进行拆单分别扣减库存，成功购买库存{}个，购买失败{}个，剩余库存{}个", subtractStockSummary.getSubtractStockSuccessCount(), subtractStockSummary.getSubtractStockFailCount(), stock.get());

                    continue;
                }


                if (subtractStockSummary.getSubtractStockResult()) {
                    log.info("扣除库存{}个成功，剩余库存{}个", currentAllSkuCount, stock.get());
                } else {
                    log.info("扣除库存失败，剩余库存{}个", stock.get());
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.info("线程已被中断，现正在退出");
        }

    }


    public void shutdown() {
        shutdown = true;
    }
}
